package com.example.jimuyutabletcontrol.network.udp;



import android.util.Log;

import com.example.jimuyutabletcontrol.utils.Constants;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * @author: HDX
 * @date: 2020\4\27 0027
 */
public class UdpSocket extends ISocket {

    private static UdpSocket udpSocket;

    public static ISocket getInstance() {
        synchronized (UdpSocket.class) {
            if (null == udpSocket) {
                udpSocket = new UdpSocket();
            }
            return udpSocket;
        }
    }

    /**
     * socket
     */
    private DatagramSocket socket;

    /**
     * 数据接收区
     */
    private DatagramPacket receiveData;

    /**
     * 是否停止UDP或UDP停止接收数据
     */
    private boolean threadRunning = false;

    private UdpSocket() {
        super();
    }

    @Override
    public void init() {
        try {
            socket = new DatagramSocket(Constants.UDP_SERVER_PORT);
            socket.setReceiveBufferSize(receiveBuffer);
            receiveData = new DatagramPacket(byteBuffer, BUFFER_LENGTH);
            receiveMessage();
            threadRunning = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void receiveMessage() {
        new Thread(() -> {
            while (threadRunning) {
                try {
                    if (null != socket && !socket.isClosed()) {
                        socket.receive(receiveData);
                    } else {
                        threadRunning = false;
                    }
                    if (null != receiveData && receiveData.getLength() > 0) {
                        String order = new String(receiveData.getData(),0,receiveData.getLength()).trim();
                        Log.e("receiveMessage",order);
                        callbackData(order);
//                        DataInputStream dataInputStream = new DataInputStream(
//                                new ByteArrayInputStream(receiveData.getData(),
//                                        receiveData.getOffset(), receiveData.getLength()));
//                        try {
//                            String message = dataInputStream.readUTF();
//                            Log.e("receiveMessage",message);
//                            callbackData(message);
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                        }
                    }
                    if (null != receiveData) {
                        receiveData.setLength(BUFFER_LENGTH);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    @Override
    public void sendMessage(String message) {
        if (!threadRunning || null == socket || null == message || socket.isClosed())
            return;
        Log.e("sendMessage",message);
        availableThreadPool.execute(() -> {
            try {
                DatagramPacket datagramPacket = new DatagramPacket(message.trim().getBytes(), message.trim().getBytes().length,
                        InetAddress.getByName(Constants.UDP_SERVER_IP), Constants.UDP_SERVER_PORT);
                socket.send(datagramPacket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    @Override
    public void sendMessage(String message, InetAddress inetAddress, int Port) {
        if (!threadRunning || null == socket || null == message || null == inetAddress || socket.isClosed())
            return;
        availableThreadPool.execute(() -> {
            try {
                DatagramPacket datagramPacket = new DatagramPacket(message.trim().getBytes(), message.trim().getBytes().length,
                        inetAddress, Port);
                socket.send(datagramPacket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    @Override
    public boolean isThreadRunning() {
        return threadRunning;
    }

    @Override
    public void release() {
        threadRunning = false;
        removeAllMessageCallback();
        if (null != socket) {
            socket.close();
            socket = null;
        }
        if (null != availableThreadPool) {
            availableThreadPool.shutdown();
        }
        availableThreadPool = null;
    }
}
